package com.easy.api.factory;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author liuyuan
 * @Date 2020/5/15 7:41 下午
 * @Version 1.0
 */
public class FactoryMethods {

    private static ConcurrentHashMap<String, Method> cacheMap = new ConcurrentHashMap<>();

    public static Method getCacheMethod(Class<?> beanClass, String method) throws Exception {
        String methodName = getMethodName(beanClass, method);
        Method useMethod = cacheMap.get(methodName);
        if(useMethod == null){
            useMethod = getUseMethod(beanClass, methodName);
            cacheMap.put(methodName,useMethod);
            return useMethod;
        }
        return useMethod;
    }

  /*  public static Method getMethod(String name) {
        return cacheMap.get(name);
    }*/

    public static String getMethodName(Class<?> beanClass, String methodName) {
        String method = beanClass.getName();
        return method + "-" + methodName;
    }

    public static Object execute(Method method, String name, Object[] args) throws InvocationTargetException, IllegalAccessException {
        return method.invoke(name, args);
    }

    public static Object cacheExecute(Class<?> beanClass,String name,Object[] args) throws Exception {
        String methodName = FactoryMethods.getMethodName(beanClass,name);
        Method method = FactoryMethods.getCacheMethod(beanClass,methodName);
        return execute(method,name,args);
    }

    private static Method getUseMethod(Class<?> beanClass, String methodName) throws Exception {
        Method useMethod = null;
        Method[] methods = beanClass.getMethods();
        for (Method method : methods) {
            String name = method.getName();
            if (name.equals(methodName)) {
                useMethod = method;
                break;
            }
        }
        if (useMethod == null) {
            throw new Exception("没有此方法");
        }
        return useMethod;
    }

}
